package com.lwj.framework.security;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;

import com.lwj.framework.degest.DigestSignature;
import org.lwj.logger.support.LogRestTemplate;
import com.lwj.framework.security.auth.OAuthUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.lang.Nullable;

public class AuthRestTemplate extends LogRestTemplate {
	private static final Logger logger = LoggerFactory.getLogger(AuthRestTemplate.class);

	private String channel;
	private DigestSignature digestSignature;

	public AuthRestTemplate(@Nullable String channel, @Nullable DigestSignature digestSignature) {
		this.channel = channel;
		this.digestSignature = digestSignature;
	}

	protected URI appendQueryParameter(URI uri, String accessToken) {
		try {
			String query = uri.getRawQuery(); // Don't decode anything here
			String queryFragment = AuthUtils.Iauthorization + "=" + URLEncoder.encode(accessToken, "UTF-8");
			if (query == null) {
				query = queryFragment;
			} else {
				query = query + "&" + queryFragment;
			}
			// first form the URI without query and fragment parts, so that it doesn't
			// re-encode some query string chars
			// (SECOAUTH-90)
			URI update = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null,
					null);
			// now add the encoded query string and the then fragment
			StringBuffer sb = new StringBuffer(update.toString());
			sb.append("?");
			sb.append(query);
			if (uri.getFragment() != null) {
				sb.append("#");
				sb.append(uri.getFragment());
			}
			return new URI(sb.toString());
		} catch (URISyntaxException e) {
			throw new IllegalArgumentException("Could not parse URI", e);
		} catch (UnsupportedEncodingException e) {
			throw new IllegalArgumentException("Could not encode URI", e);
		}

	}

	@Override
	protected ClientHttpRequest createRequest(URI uri, HttpMethod method) throws IOException {
		AuthEntity authEntity = new AuthEntity();
		authEntity.setIsd(OAuthUtils.True);
		authEntity.setChn(channel);
		try {
			String accessToken = digestSignature.encode(authEntity);
			uri = appendQueryParameter(uri, accessToken);
		} catch (Exception e) {
			logger.error("AuthRestTemplate digestSignature encode token error", e);
		}
		return super.createRequest(uri, method);

	}

}
